package Function.ItemUse;

import FCRendering.FCRBattleOrderConstant;
import FCRendering.FCRConstants;
import Frame.battleanimation.AnimationUtil;
import Function.FCItemForTankHelper;
import Function.FCMutilPlayCache;
import Function.FCMutilPlayTankCache;
import VWorldGameStudio.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.function.BiConsumer;

import static FCRendering.FCRMaster.*;

public class WeaponTypeItemUse extends AItemUse {
    @Override
    public ItemUseResult directUse() {
        return new ItemUseResult().useless();
    }

    @Override
    public ItemUseResult useInMapTarget(int x, int y) {
        return new ItemUseResult().useless();
    }

    @Override
    public ItemUseResult useForPlayerTarget(FCPlayerInfo p) {
        return new ItemUseResult().useless();
    }

    @Override
    public ItemUseResult useForTankTarget(FCTank t) {
        return new ItemUseResult().useless();
    }

    int hitRate = 0;
    int cirt = 0;

    //武器只能打怪物
    @Override
    public ItemUseResult useForMonsterTarget(FCBattleOrder battleOrder, FCMonster m) {
        FCPlayerBattleWrap wrap = FCPlayerBattleWrap.findBattleWrapByName(keepPlayer.getAliasUID(), keepPlayer.getName());
        hitRate = keepPlayer.getHitRate(wrap);
        cirt = keepPlayer.getCritRate(wrap);//暴击值（最大100）
        if(wrap.isBattleDriverTank()){
            //那就只计算坦克的命中值
            FCTank tank = tankLib.getTankOfID(keepPlayer.getPlayertank1(), keepPlayer.getPlayertankHostId());
            if(tank != null) {
                hitRate = tank.getHitRate(wrap, keepPlayer.getSpeed2(), wrap.getBattlePlayerSelectMenu());
                //TODO 还要加上职业的战车驾驶修正？
            }else {
                hitRate = 0;
            }
        }
        ArrayList<FCMonster> now2AliveMonsters = getSortNowAliveMonsters(hitRate, battleOrder, m);
        ArrayList<FCMonster> toAttckMonster = null;
        int plate = 0;


        HashMap<String, String> msTips = new HashMap<>();
        //STEP 1 破甲攻击
        if (useItem.getDesdefense() > 0) {
            toAttckMonster = getTargetMonster(useItem.getDesdefenseNum(), now2AliveMonsters);
            for (FCMonster ms : toAttckMonster) {
                //TODO 有甲的就破甲，没的就pass
                if (battleOrder.randomV2 * 100 <= ms.getAttackRate(hitRate)) {
                    if (ms.getPlateArmour() > 0) {
                        plate = ms.getPlateArmour() - useItem.getDesdefense();
                        plate = Math.max(0, plate);
                        String key = (fcv.getBattleMonster().indexOf(ms) + 1) + "号"+ms.getChName();
                        msTips.put(key, "SP减"+(ms.getPlateArmour()-plate));

                        ms.setPlateArmour(plate);
//                        if (m.getPlateArmour() == 0) {
//                            fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号 被完全破甲了");
//                            fcv.showMessage();
//                        }
                    }
                } else {
                    if (toAttckMonster.indexOf(ms) == 0) {
                        //TODO 第一个都没打中，后面的就别谈了
                        break;
                    }
                }
            }
        }
        //STEP 2 破坏攻击
        if (useItem.getSubdefense() > 0) {
            toAttckMonster = getTargetMonster(useItem.getSubdefenseNum(), now2AliveMonsters);
            for (FCMonster ms : toAttckMonster) {
                if (battleOrder.randomV2 * 100 <= ms.getAttackRate(hitRate)) {
                    //TODO 找最低防御的来打
                    MstAttack mstAttack = ms.getMinDefenseMSAttack();
                    if (mstAttack != null && mstAttack.getDefense() > 0) {
                        //TODO 破坏掉他
                        int de = mstAttack.getDefense() - useItem.getSubdefense();
                        de = Math.max(0, de);
                        mstAttack.setDefense(de);
//                        if (mstAttack.getDefense() == 0) {
//                            fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号的" + mstAttack.getName() + "被破坏了");
//                            fcv.showMessage();
//                        }
                    }
                } else {
                    if (toAttckMonster.indexOf(ms) == 0) {
                        //TODO 第一个都没打中，后面的就别谈了
                        break;
                    }
                }
            }
        }
        //STEP 3 物理攻击
        if (useItem.getAttackHurt() > 0) {
            toAttckMonster = getTargetMonster(useItem.getAttackNum(), now2AliveMonsters);
            for (FCMonster ms : toAttckMonster) {
                boolean isBaoJi = false;
                String key = (fcv.getBattleMonster().indexOf(ms) + 1) + "号"+ms.getChName();
                String data = msTips.get(key);
                if(data == null){
                    data = "";
                }
                if (battleOrder.randomV2 * 100 <= ms.getAttackRate(hitRate)) {
                    int attckHurt = (int) (useItem.getAttackHurt() + keepPlayer.getStrength() / 10);
                    if (useItem.getCatalog().equals("tank")) {
                        //战车道具，那伤害要和战车等级有关了
                        attckHurt = useItem.getAttackHurt();
                        if (useItem.getType().equals("shell")) {//如果是炮弹则还要加上主炮伤害
                            FCItem gun1Item = itemLib.getItemOfID(keepItemTank.getGunID());
                            attckHurt += gun1Item.getAttackHurt() * 1;
                        }
                        attckHurt = (int)(attckHurt * (1 + (double)keepPlayer.getSpeed2()*0.0005));
                    }

                    int addAttack = wrap.getLongTermVal(FCRBattleOrderConstant.S_AddAttack);
                    if(addAttack != -1){
                        attckHurt += addAttack;
                    }

                    int toMCirt = cirt;
                    if("PD_tieDan".equals(useItem.getName()) && (ms.getType().equals("bionic")
                    || ms.getType().equals("biochemistry"))){
                        //TODO 铁弹如果怪物是生物系就容易会心一击
                        toMCirt += (100*useItem.getCrit()*0.4);
                    }else {
                        //比如钢弹
                        toMCirt += (100*useItem.getCrit()*0.4);
                    }

                    if (battleOrder.randomV3 * 100 < toMCirt) {//产生了暴击
                        attckHurt += attckHurt;
                        isBaoJi = true;
                    }
                    if (ms.getPlateArmour() > 0) {//怪物还有甲，则伤害要减少了,掉3/4 attckHurt甲和1/4伤害再-防御
                        plate = ms.getPlateArmour() - 3 * attckHurt / 4;
                        plate = Math.max(0, plate);
                        ms.setPlateArmour(plate);
                        attckHurt = (int) (attckHurt / 4);
                    }
                    attckHurt = attckHurt - ms.getMsDefense();
                    attckHurt = Math.max(attckHurt, 1);
                    int msBlood = ms.getBlood() - attckHurt;
                    msBlood = Math.max(0, msBlood);
                    ms.setShowAttckHurt(attckHurt);
                    ms.setBlood(msBlood);
//                    fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + keepPlayer.getChName() + "攻击" + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号,伤害"
//                            + attckHurt + (isBaoJi ? "~暴击" : ""));
//                    fcv.showMessage();

                    data += " HP减"+attckHurt+(isBaoJi ? "(~会心一击)" : "");
                    System.out.println("攻击" + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号,伤害"
                            + attckHurt + (isBaoJi ? "~暴击" : ""));
                } else {
//                    fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + keepPlayer.getChName() + "攻击" + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号,未命中");
//                    fcv.showMessage();
                    System.out.println("攻击" + ms.getChName() + "-" + (fcv.getBattleMonster().indexOf(ms) + 1) + "号,未命中");
                    data += " 被攻击未命中";
                    if (toAttckMonster.indexOf(ms) == 0) {
                        //TODO 第一个都没打中，后面的就别谈了
                        break;
                    }
                }
                if(ms.getIsDeath()){
                    data += " 被消灭了";
                }
                msTips.put(key, data);
            }
        }
        //STEP 4 属性攻击,特殊炮弹啊等
        if (!useItem.getElements().equals("null")) {
            toAttckMonster = getTargetMonster(useItem.getAttackNum(), now2AliveMonsters);
            for (FCMonster ms : toAttckMonster) {
                if (!ms.getIsDeath() && battleOrder.randomV2 * 100 <= ms.getAttackRate(hitRate)) {
                    checkElement(msTips, useItem,ms, useItem.getElements(), battleOrder.randomV4);
                } else {
                    if (toAttckMonster.indexOf(ms) == 0) {
                        //TODO 第一个都没打中，后面的就别谈了
                        break;
                    }
                }
            }
        }
        msTips.forEach(new BiConsumer<String, String>() {
            @Override
            public void accept(String s, String s2) {
                fcv.getMessage().add(s+s2);
                fcv.showMessage();
                fcv.endBattleInfo(s+s2);
            }
        });

        //STEP 5 减弹操作
        if (wrap.getHostUid().equals(gameSave.HOST_UID)) {
            //TODO 判断是本地的枪具才 减少一发子弹
            if (useItem.getType().equals("gun1") || useItem.getType().equals("se") || useItem.getType().equals("gun2")) {
                FCItemForTankHelper.subDanyao(useItem);
            } else if (useItem.getType().equals("shell")) {
                //特殊炮弹的
                FCItem dipanItem = itemLib.getItemOfID(keepItemTank.getChassisID());
                FCItemForTankHelper.subShellIndex(dipanItem, 1, wrap.getBattlePlayerSelectPaoDanIndex());
            }
        }
        return null;
    }


    public static ArrayList<FCMonster> getTargetMonster(int n, ArrayList<FCMonster> src) {
        ArrayList<FCMonster> ret = new ArrayList<>(n);
        n = Math.min(src.size(), n);
        for (int i = 0; i < n; i++) {
            ret.add(src.get(i));
        }
        return ret;
    }


    /**
     * TODO 属性规则抗性最大100：例如中毒免疫率公式是目标闪避率+目标属性抗性/100。中毒伤害是属性攻击值*（1-目标属性抗性/100）
     *
     * @param monster
     * @param element
     */
    public static void checkElement(HashMap<String, String> msTips, FCItem useItem, FCMonster monster, String element, float randomv4) {
        int mosnterResistance = monster.getLongTermVal(element);
        mosnterResistance = mosnterResistance == -1 ? 0 : mosnterResistance;
        int msDogeRate = monster.getMsDogeRate();
        String key = (fcv.getBattleMonster().indexOf(monster) + 1) + "号"+monster.getChName();
        String data = msTips.get(key);
        if(data == null){
            data = "";
        }
        if (element.equals(FCRBattleOrderConstant.S_Fog)) {
            //烟雾的话直接几率中和不中
            if (100*randomv4 < useItem.getElementsValue()) {
                //中了,状态图标
                monster.addlongTermState(FCRBattleOrderConstant.S_Fog, 1, useItem.getElementsRound());
                //防御力降低 本身防御的10%
                monster.addlongTermState(FCRBattleOrderConstant.S_Defense, (int)(-monster.getDefense()*0.1), useItem.getElementsRound());
                data += " 被烟雾笼罩了";
            }
        }else if (element.equals(FCRBattleOrderConstant.S_Confusion)) {
            //混乱的话直接几率中和不中
            if (100*randomv4 < useItem.getElementsValue()) {
                //中了,状态图标
                monster.addlongTermState(FCRBattleOrderConstant.S_Confusion, 1, useItem.getElementsRound());
                data += " 混乱了";
            }
        }else if (element.equals(FCRBattleOrderConstant.S_Cement)) {
            //水泥的话直接几率中和不中
            if (100*randomv4 < useItem.getElementsValue()) {
                //中了,状态图标
                monster.addlongTermState(FCRBattleOrderConstant.S_Cement, 1, useItem.getElementsRound());
                data += " 陷入水泥了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Sleep)) {
            mosnterResistance += monster.getSleepResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Sleep, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 睡着了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Paralysis)) {
            mosnterResistance += monster.getParalysisResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Paralysis, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 麻痹了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Gas)) {
            mosnterResistance += monster.getGasResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Gas, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 中毒了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Fire)) {
            mosnterResistance += monster.getFireResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Fire, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 着火了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Acid)) {
            mosnterResistance += monster.getAcidResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Acid, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 中酸了";
            }
        } else if (element.equals(FCRBattleOrderConstant.S_Frozen)) {
            mosnterResistance += monster.getFrozenResistance();
            System.out.println("怪物闪避 " + msDogeRate + " 抗性 " + mosnterResistance + " 随机数：" + (randomv4 * 100));
            if (randomv4 * 100 >= ((int)(msDogeRate/2) + mosnterResistance)) {
                //TODO 中了
                monster.addlongTermState(FCRBattleOrderConstant.S_Frozen, useItem.getElementsValue(), useItem.getElementsRound());
                data += " 受寒了";
            }
        }

        msTips.put(key, data);
    }
}
